<script>
import { GlFormGroup, GlFormInput, GlButton } from '@gitlab/ui';
import { s__ } from '~/locale';
import * as i18n from './i18n';

export default {
  components: {
    GlFormGroup,
    GlFormInput,
    GlButton,
  },
  props: {
    validationState: {
      type: Object,
      required: false,
      default: () => ({}),
    },
  },
  data() {
    return {
      identifiers: [{ identifierCode: '', identifierUrl: '' }],
    };
  },
  watch: {
    identifiers() {
      this.emitChanges();
    },
  },
  methods: {
    emitChanges() {
      this.$emit('change', {
        identifiers: this.identifiers.map((i) => ({
          name: i.identifierCode,
          url: i.identifierUrl,
        })),
      });
    },
    addIdentifier() {
      this.identifiers.push({ identifierCode: '', identifierUrl: '' });
    },
    removeIdentifier(index) {
      this.identifiers.splice(index, 1);
    },
    // null is when the user didn't input anything yet
    // false when the user provided invalid input and
    // true when the validation passes
    validationStateIdentifierUrl(index) {
      return this.validationState.identifiers?.[index]?.identifierUrl ?? null;
    },
    validationStateIdentifierCode(index) {
      return this.validationState.identifiers?.[index]?.identifierCode ?? null;
    },
    rowHasError(index) {
      return (
        this.validationStateIdentifierUrl(index) === false ||
        this.validationStateIdentifierCode(index) === false
      );
    },
  },
  i18n: {
    errorIdentifierCode: i18n.ERROR_IDENTIFIER_CODE,
    errorIdentifierUrl: i18n.ERROR_IDENTIFIER_URL,
    title: s__('Vulnerability|Identifiers'),
    description: s__(
      'Vulnerability|Enter the associated CVE or CWE entries for this vulnerability.',
    ),
    identifierCode: s__('Vulnerability|Identifier code'),
    identifierUrl: s__('Vulnerability|Identifier URL'),
    addIdentifier: s__('Vulnerability|Add another identifier'),
    removeIdentifierRow: s__('Vulnerability|Remove identifier row'),
  },
};
</script>

<template>
  <section>
    <header class="gl-pt-4 gl-my-6 gl-border-t-gray-100 gl-border-t-solid gl-border-t-1">
      <h3 class="gl-mt-0 gl-mb-3">
        {{ $options.i18n.title }}
      </h3>
      <p data-testid="section-description">
        {{ $options.i18n.description }}
      </p>
    </header>
    <div
      v-for="(identifier, index) in identifiers"
      :key="index"
      data-testid="identifier-row"
      class="gl-display-flex gl-mb-6"
    >
      <gl-form-group
        :label="$options.i18n.identifierCode"
        :label-for="`form-identifier-code-${index}`"
        :state="validationStateIdentifierCode(index)"
        :invalid-feedback="$options.i18n.errorIdentifierCode"
        class="gl-mr-6 gl-mb-0"
      >
        <gl-form-input
          :id="`form-identifier-code-${index}`"
          v-model.trim="identifier.identifierCode"
          :state="validationStateIdentifierCode(index)"
          type="text"
          @input="emitChanges"
        />
      </gl-form-group>
      <gl-form-group
        :label="$options.i18n.identifierUrl"
        :state="validationStateIdentifierUrl(index)"
        :invalid-feedback="$options.i18n.errorIdentifierUrl"
        :label-for="`form-identifier-url-${index}`"
        class="gl-flex-grow-1 gl-mb-0"
      >
        <gl-form-input
          :id="`form-identifier-url-${index}`"
          v-model.trim="identifier.identifierUrl"
          :state="validationStateIdentifierUrl(index)"
          type="text"
          @input="emitChanges"
        />
      </gl-form-group>
      <gl-button
        v-if="index > 0"
        class="gl-ml-4 gl-shadow-none!"
        :class="rowHasError(index) ? 'gl-align-self-center' : 'gl-align-self-end'"
        icon="remove"
        :aria-label="$options.i18n.removeIdentifierRow"
        @click="removeIdentifier(index)"
      />
      <!--
        The first row does not contain a remove button and this creates
        a misalignment. This button is here as a placeholder to align the rows,
        it's not visible to the user but it occupies the space hence aligns the
        rows properly.
      -->
      <gl-button
        v-else
        class="gl-align-self-end gl-ml-4 gl-shadow-none gl-visibility-hidden"
        icon="remove"
      />
    </div>
    <gl-button category="secondary" variant="confirm" @click="addIdentifier">{{
      $options.i18n.addIdentifier
    }}</gl-button>
  </section>
</template>
